#include "vp.h"
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <cmath>
using std::pow;
using std::exp;
using std::rand;
using std::ofstream;
using std::ifstream;
using std::endl;
using std::cout;
using std::cerr;
using std::ios;

perceptron::perceptron() {
    norm = 2;
    radius = 100;
}

perceptron::~perceptron() {
}

void perceptron::set(int n, float r) {
    norm = n;
    radius = r;
}

void perceptron::accumulate(float z) {
    int i;
    while (wacc.size() < w.size()) {
        wacc.push(0.0f);
    }
    for (i = w.size(); i >= 0; i--) {
        wacc[i] += w[i] / z;
    }
}

void perceptron::normalize(float z) {
    int i;
    for (i = w.size(); i >= 0; i--) {
        wacc[i] /= z;
    }
}

void perceptron::train(Array <svector*>& trainset, int T) {
    int j, t, y;
    int len = trainset.size();
    wacc.clear();
    w.clear();
    for (t = 0; t < T; t++) {
        for (j = 0; j < len; j++) {
            svector* x = trainset[j];
            y = x->getClass();
            real sim = y * x->dot(w);
            if (sim <= 0) {
                x->update(w);
            }
            accumulate(T * len);
        }
        cerr << '.';
    }
    cerr << endl;
    //normalize(T*len);
}

void perceptron::test(const Array<svector*>& testset, Array<real>& pred) {
    int j;
    int len = testset.size();
    for (j = 0; j < len; j++) {
        svector* x = testset[j];
        real sim = x->dot(wacc);
        pred.push(sim);
    }
}

void perceptron::read(const char* file) {
    int i, wlen;
    real val;
    ifstream ifs(file);
    ifs >> wlen;
    for (i = 0; i < wlen; i++) {
        ifs >> val;
        wacc.push(val);
    }
    ifs.close();
}

void perceptron::write(const char* file) {
    int i;
    int wlen = wacc.size();
    ofstream ofs(file);
    ofs << wlen << endl;
    for (i = 0; i < wlen; i++) {
        ofs << wacc[i] << endl;
    }
    ofs.close();
}
